import {
  DialoguePageResultDto,
  DialogueResultDto,
  DialoguesQuery,
  DialoguesQueryVariables,
  MessageResultDto,
  MessagesQuery,
  MessagesQueryVariables,
} from '@/gql'
import { makeAutoObservable, runInAction } from 'mobx'
import { SocketBO } from '../../types/kf'
// import {client} from "@/app";
import { client } from '@/global'
import { DialoguesDocument, MessagesDocument } from '@/gql'

class KfModel {
  /* ******************* 会话列表 ******************* */
  dialogueCurrentPage = 1 // 会话列表当前页
  dialogueList: DialogueResultDto[] = [] // 会话列表
  hasMoreDialogue = false
  currentDialogue?: DialogueResultDto // 当前会话

  nextDialoguePage() {
    this.dialogueCurrentPage++
    this.flushDialogueData().then()
  }

  async initState() {
    this.dialogueCurrentPage = 1
    this.dialogueList = []
    this.flushDialogueData()
  }
  /**
   * 刷新会话列表数据
   */
  async flushDialogueData() {
    let result = await client?.query<DialoguesQuery, DialoguesQueryVariables>({
      query: DialoguesDocument,
      variables: {
        current: this.dialogueCurrentPage,
        size: 20,
      },
    })
    if (!result) return
    const {
      data: { dialogues },
    } = result
    runInAction(() => {
      this.dialogueList.push(...(dialogues.records as DialogueResultDto[]))
      this.hasMoreDialogue = dialogues.current < dialogues.pages
    })
  }

  /**
   * 切换会话
   * @param target 目标会话
   */
  changeCurrentDialogue(target: DialogueResultDto) {
    this.currentDialogue = target
    // 清除未读标记
    let currentDialogueEl = this.dialogueList.find((it) => it.id === target.id)
    if (currentDialogueEl) {
      currentDialogueEl.unreadTotal = 0
      let currentDialogueElInx = this.dialogueList.indexOf(currentDialogueEl)
      this.dialogueList.splice(currentDialogueElInx, 1, currentDialogueEl)
    }

    // 加载会话消息
    this.messageCurrent = 1
    this.messageList = []
    this.flushMessageData().then()
  }

  updateDialogue(socketBO: SocketBO) {
    if (socketBO.event !== 'message') {
      return
    }

    let { dialogue, message } = socketBO.message

    // 判断新的会话是否就是当前的会话，如果是的话还需要额外更新消息列表
    let currentDialogue = this.dialogueList.find((it) => it.id === dialogue.id) || ({} as DialogueResultDto) // 当前会话在会话列表当中的元素
    let elInx = this.dialogueList.indexOf(currentDialogue)
    let firstNotTopEl = this.dialogueList.find((it) => !it.isTop) // 首个非置顶的会话元素
    let firstNotTopElInx = (firstNotTopEl && this.dialogueList.indexOf(firstNotTopEl)) || 0
    currentDialogue = { ...currentDialogue, ...(dialogue as unknown as DialogueResultDto) }

    if (currentDialogue.id === this.currentDialogue?.id) {
      currentDialogue.unreadTotal = 0
      this.messageList.splice(0, 0, message)
    }

    this.dialogueList.splice(elInx, 1)
    this.dialogueList.splice(firstNotTopElInx, 0, currentDialogue)
    // 判断新的会话是否已经存在会话列表
  }

  /* ******************* 消息列表 ******************* */
  messageCurrent = 0 // 消息列表当前页
  messageList: MessageResultDto[] = [] //右侧消息列表
  hasMoreMessage = false
  messageLoading = false

  setMessageLoading = (state: boolean) => {
    this.messageLoading = state
  }
  nextMessagePage() {
    this.messageCurrent++
    this.flushMessageData().then()
  }

  /**
   * 刷新会话列表数据
   */
  async flushMessageData() {
    console.log(`刷新 ${this.messageCurrent}`)
    if (!this.currentDialogue) return
    this.setMessageLoading(true)
    client
      ?.query<MessagesQuery, MessagesQueryVariables>({
        query: MessagesDocument,
        variables: {
          current: this.messageCurrent,
          size: 20,
          dialogueId: this.currentDialogue.id,
        },
      })
      .then(({ data }) => {
        runInAction(() => {
          this.messageList.push(...(data.messagePage.records as MessageResultDto[]))
          this.hasMoreMessage = Number(data.messagePage.current) < Number(data.messagePage.pages)
        })
        this.setMessageLoading(false)
      })
  }

  addDialogueList(data: DialoguePageResultDto) {
    this.dialogueList.push(...data.records)
    this.hasMoreDialogue = Number(data.current) < Number(data.pages)
  }

  constructor() {
    makeAutoObservable(this, {}, { autoBind: true })
  }
}

export default KfModel
export const kfModel = new KfModel()
